<template>
    <!-- 消息弹框 -->
    <el-dialog v-model="isShow" width="656" @close="close">
        <template #header>
            <div class="print_header">
                <h4>打印预览</h4>
                <span>(多库位打印仅提供第一张)</span>
            </div>
        </template>
        <div class="print_context" v-loading="loading">
            <div class="bar_code">
                <svg class="bar_code_svg" ref="barcodeRef"></svg>
                <!-- <img src="@/assets/images/depot/yiweima.png" alt=""> -->
            </div>
            <h4>{{ codeName }}</h4>
            <div v-if="!printPlanIsShow">
                <div class="print_context_machine">
                    <img class="machine_img" src="@/assets/images/depot/icon_dayinji.png" alt="">
                    <span class="machine_text color_hei">当前热敏机：</span>
                    <span class="machine_text color_hui mr20 w218">
                        <span v-for="(item, index) in usbPrinters" :key="item">{{ index }}</span>
                        <span v-if="!Object.keys(usbPrinters).length">暂无热敏机</span>
                    </span>
                    <span v-if="onlineUsbBool && initBool" class="machine_text color_lan mr30">已连接</span>
                    <el-button type="primary" link
                        v-if="Object.keys(usbPrinters).length && (!onlineUsbBool || !initBool)"
                        @click="connectState()">连接</el-button>
                    <el-button type="primary" link v-if="!Object.keys(usbPrinters).length"
                        @click="getPrinters()">搜索设备</el-button>
                </div>
                <el-form ref="ruleFormRef" :model="formValue" :rules="rules" label-width="120px" class="demo-ruleForm">
                    <el-form-item label="请选择打印数量" prop="printQuantity">
                        <el-input-number v-model="formValue.printQuantity" :min="1" :max="99" />
                    </el-form-item>
                </el-form>
            </div>
            <div v-if="printPlanIsShow" class="print_context_progress">
                <el-progress style="width: 456px" color="#0094FF" text-inside status="success" stroke-width="20"
                    :show-text="false" :percentage="(printPlan / (barcodePrintData.length *
                        jsonObj.printerImageProcessingInfo.printQuantity)) * 100">
                </el-progress>
                <p>打印中...（{{ printPlan }}/{{ barcodePrintData.length *
                    jsonObj.printerImageProcessingInfo.printQuantity }}）
                </p>
            </div>
        </div>
        <template #footer>
            <span class="dialog-footer">
                <el-button @click="close">取消</el-button>
                <el-button type="primary" @click="startPrintJobTest()">打印</el-button>
            </span>
        </template>
    </el-dialog>
</template>
<script setup lang="ts">
import { ref, onMounted, defineExpose, nextTick } from 'vue'
import Socket from "@/utils/socket";
import NMPrintSocket from "@/utils/print";
import JsBarcode from 'jsbarcode'
import { ElMessage } from 'element-plus'

const barcodeRef = ref()
const ruleFormRef = ref()
const isShow = ref(false)
const printSocketOpen = ref<Boolean>(false)
const onlineUsbBool = ref(false)
const usbSelectPrinter = ref('')
const usbPrinters = ref<any>({})
const nMPrintSocket = ref<any>(null)
const initBool = ref(false)
const formValue = ref({
    printQuantity: 1
})
const jsonObj = ref({
    printerImageProcessingInfo: {
        printQuantity: 1,  // 每个库位码打印的数量
    }
});
const density = ref(3)       // 浓度
const label_type = ref(1)    // 纸张类型
const print_mode = ref(1)    // 打印模式
const printPlan = ref(0)  // 已打印数量
const printPlanIsShow = ref(false)     // 开始打印
const loading = ref(false)
const barcodePrintData = ref<Array<any>>([])
const codeName = ref('')

const validatePass = (rule: any, value: any, callback: any) => {
    return /^\+?[1-9]\d*$/.test(value)
}
const rules = ref({
    printQuantity: [
        {
            required: true,
            message: '请输入打印数量',
            trigger: 'change',
        },
        {
            validator: validatePass,
            message: '请输入1到99的正整数',
            trigger: 'change'
        }
    ]
})



// 打印初始化
const int = async (data: Array<any>) => {
    isShow.value = true
    barcodePrintData.value = data
    codeName.value = data[0].elements[0].json.value
    const options = {
        // format: 'EAN13', // 格式
        height: 100,
        // text: "覆盖显示的文本",
        fontSize: 16,
        // background: '#ccc',
        lineColor: 'black',
        displayValue: false,
    }
    await nextTick();
    JsBarcode(barcodeRef.value, data[0].elements[0].json.value, options)
}

//更新打印机列表
const getPrinters = async () => {
    loading.value = true
    if (!printSocketOpen.value) {
        ElMessage.error('打印服务未开启')
        loading.value = false
        return
    }
    try {
        const allPrintersRes = await nMPrintSocket.value.getAllPrinters();
        if (allPrintersRes.resultAck.errorCode === 0) {
            const allPrinters = JSON.parse(allPrintersRes.resultAck.info);
            usbPrinters.value = { ...allPrinters };
            usbSelectPrinter.value = Object.keys(usbPrinters.value)[0];
            selectOnLineUsbPrinter()
            init()
        } else {
            ElMessage.error('没有在线的打印机')
            loading.value = false
        }
    } catch (err) {
        console.error(err);
    }
}
const connectState = () => {
    loading.value = true
    if (!printSocketOpen.value) {
        ElMessage.error('打印服务未开启')
        loading.value = false
        return
    }
    if (!onlineUsbBool.value) {
        selectOnLineUsbPrinter()
    }
    if (!initBool.value) {
        init()
    }
}
// 连接打印机
const selectOnLineUsbPrinter = async () => {
    if (!printSocketOpen.value) {
        ElMessage.error('打印服务未开启')
        loading.value = false
        return
    }
    try {
        const res = await nMPrintSocket.value.selectPrinter(
            usbSelectPrinter.value,
            parseInt(usbPrinters.value[usbSelectPrinter.value])
        );
        if (res.resultAck.errorCode === 0) {
            ElMessage.success('设备连接成功')
            loading.value = false
            onlineUsbBool.value = true;
        } else {
            loading.value = false
            ElMessage.error('设备连接失败')
            onlineUsbBool.value = false;
        }
    } catch (err) {
        loading.value = false
        console.error(err);
    }
}
//初始化SDK
const init = async () => {
    if (!printSocketOpen.value) {
        ElMessage.error('打印服务未开启')
        loading.value = false
        return
    }
    //初始化数据
    try {
        const res = await nMPrintSocket.value.initSdk({ fontDir: "" });
        if (res.resultAck.errorCode == 0) {
            ElMessage.success('设备通信连接成功')
            loading.value = false
            initBool.value = true;
        } else {
            ElMessage.error('设备通信连接失败')
            loading.value = false
            initBool.value = false;
        }
    } catch (err) {
        console.error(err);
        loading.value = false
    }
}

// 开始打印
const startPrintJobTest = async () => {
    if (!printSocketOpen.value) {
        ElMessage.error('打印服务未开启')
        return
    }
    ruleFormRef.value.validate((valid: any) => {
        if (valid) {
            jsonObj.value.printerImageProcessingInfo.printQuantity = formValue.value.printQuantity
            batchPrintJob(barcodePrintData.value);
            loading.value = true
        } else {
            console.log('error submit!')
            return false
        }
    })
}

//批量打印列表数据
const batchPrintJob = async (list: Array<any>) => {
    const printQuantity =
        jsonObj.value.printerImageProcessingInfo.printQuantity; // 打印数量
    console.log(printQuantity)
    try {
        const startRes = await nMPrintSocket.value.startJob(
            density.value,  // 浓度
            label_type.value, // 纸张类型
            print_mode.value,  // 打印模式
            list.length * printQuantity
        );
        if (startRes.resultAck.errorCode == 0) {
            // 提交打印任务
            let time: any = null
            printPlanIsShow.value = true
            printPlan.value += 1
            time = setInterval(() => { // 进度条打印逻辑
                if (printPlan.value < list.length * jsonObj.value.printerImageProcessingInfo.printQuantity) {
                    printPlanIsShow.value = true
                    printPlan.value += 1
                } else {
                    printPlanIsShow.value = false
                    printPlan.value = 0
                    clearInterval(time)
                }
            }, 3000)
            await printTag(list, 0);
        }
    } catch (err) {
        console.error(err);
    }
}
// 绘制打印标签
const printTag = async (list: Array<any>, x: number) => {
    //设置画布尺寸
    try {
        const res = await nMPrintSocket.value.InitDrawingBoard(
            list[x].InitDrawingBoardParam
        );
        if (res.resultAck.errorCode != 0) {
            return;
        }
        // 提交打印任务
        printItem(list, x, list[x].elements, 0);
    } catch (err) {
        console.error(err);
    }
}
const printItem = async (list: Array<any>, x: number, item: any, i: number) => {
    loading.value = false
    try {
        if (i < item.length) {
            let arrParse;
            switch (item[i].type) {
                case "text":
                    //绘制文本
                    arrParse = await nMPrintSocket.value.DrawLableText(item[i].json);
                    if (arrParse.resultAck.errorCode != 0) {
                        return;
                    }
                    i++;
                    await printItem(list, x, item, i);
                    break;
                case "qrCode":
                    arrParse = await nMPrintSocket.value.DrawLableQrCode(item[i].json);
                    //绘制二维码
                    if (arrParse.resultAck.errorCode !== 0) {
                        return;
                    }
                    i++;
                    await printItem(list, x, item, i);
                    break;
                case "barCode":
                    //绘制一维码
                    arrParse = await nMPrintSocket.value.DrawLableBarCode(
                        item[i].json
                    );
                    if (arrParse.resultAck.errorCode !== 0) {
                        return;
                    }
                    i++;
                    await printItem(list, x, item, i);
                    break;
                case "line":
                    //绘制线条
                    arrParse = await nMPrintSocket.value.DrawLableLine(item[i].json);
                    if (arrParse.resultAck.errorCode !== 0) {
                        return;
                    }
                    i++;
                    await printItem(list, x, item, i);
                    break;
                case "graph":
                    //绘制边框
                    arrParse = await nMPrintSocket.value.DrawLableGraph(item[i].json);
                    if (arrParse.resultAck.errorCode != 0) {
                        return;
                    }

                    i++;
                    await printItem(list, x, item, i);
                    break;
                case "image":
                    //绘制边框
                    arrParse = await nMPrintSocket.value.DrawLableImage(item[i].json);
                    if (arrParse.resultAck.errorCode != 0) {
                        return;
                    }
                    i++;
                    await printItem(list, x, item, i);
                    break;
            }
        } else {
            //遍历完成，开始打印
            const commitRes = await nMPrintSocket.value.commitJob(
                null,
                JSON.stringify(jsonObj.value)
            );
            //回调页码为数据总长度且回调打印份数数据等于当前页需要打印的份数数据时，结束打印任务
            if (
                commitRes.resultAck.printQuantity == list.length && commitRes.resultAck.onPrintPageCompleted == jsonObj.value.printerImageProcessingInfo.printQuantity
            ) {
                //结束打印任务
                const endRes = await nMPrintSocket.value.endJob();
                if (endRes.resultAck.errorCode === 0) {
                    ElMessage.success('打印完成')
                }
                return;
            }
            //回调为提交成功，同时数据未发送完成时，可继续提交数据
            if (commitRes.resultAck.errorCode === 0 && x < list.length - 1) {
                //数据提交成功，数据下标+1
                console.log("发送下一页打印数据： ");
                x++;
                await printTag(list, x);
            }
        }
    } catch (err) {
        console.error(err);
    }
}

const close = () => {
    loading.value = false
    isShow.value = false
    jsonObj.value.printerImageProcessingInfo.printQuantity = 1
    formValue.value.printQuantity = 1
}

onMounted(() => {
    // 创建socket实例
    const socketData = new Socket("ws://127.0.0.1:37989");

    socketData.open(
        (openBool: Boolean) => {
            console.log(openBool, "openBool");
            printSocketOpen.value = openBool;
        },
        (msg: any) => {
            if (msg.resultAck.callback != undefined) {
                const callbackName = msg.resultAck.callback.name;
                const msgInfo = msg.resultAck.info;
                if (callbackName == "onCoverStatusChange") {
                    //盒盖状态：0-闭合、1-打开
                    console.log("盒盖状态", msgInfo.capStatus);
                } else if (callbackName == "onElectricityChange") {
                    //"power" : 0-4, // 电池电量等级（共5档）
                    console.log("电池电量等级", msgInfo.power);
                }
            }
        }
    );
    // 创建打印实例
    nMPrintSocket.value = new NMPrintSocket(socketData);
})
defineExpose({ int })
</script>
<style lang="scss" scoped>
@import url(../style/index.scss);
</style>